package com.hb.medical_research_system.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hb.medical_research_system.common.Results;
import com.hb.medical_research_system.service.ArticleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.*;

@Api(tags = "文献")
@Slf4j
@RestController
@RequestMapping("/article")
public class ArticleController {

    private final RestHighLevelClient client;
    private final ObjectMapper objectMapper;
    private final ArticleService articleService;

    @Autowired
    public ArticleController(RestHighLevelClient client, ObjectMapper objectMapper, ArticleService articleService) {
        this.client = client;
        this.objectMapper = objectMapper;
        this.articleService = articleService;
    }

    @ApiOperation("润骞接口")  // Demo operation
    @PostMapping("/hrx")
    private Results rx(){
        Map<String, Map<String, Object>> maps = new HashMap<>();
        for (int i = 0; i < 5; i++) {
            Map<String, Object> map = new HashMap<>();
            map.put("articleId",i);
            map.put("title", "润骞要的数据捏");
            map.put("summary","润骞要的数据捏润骞要的数据捏润骞要的数据捏润骞要的数据捏润骞要的数据捏润骞要的数据捏润骞要的数据捏型");
            map.put("another","侯润骞");
            map.put("keyword","母猪,生产,护理");
            map.put("likes",1);
            map.put("click",100);
            maps.put(String.valueOf(i),map);
        }
        return new Results(Results.SUCCESS, maps, "润骞要的数据捏");
    }


    @PostMapping("/add")
    public Results add(String address){
        return articleService.add(address);
    }

//    @GetMapping("/title")
//    public Results searchByTitle(String title) {
//        List<Article> articles = articleService.searchByTitle(title);
//        return new Results(1,articles, "查询成功");
//    }
//
//    @GetMapping("/title2")
//    public Results searchByTitle2(String title, int page, int pageSize) {
//        Page<Article> articlePage = articleService.searchByTitle2(title, page, pageSize);
//        return new Results(1,articlePage,"查询成功");
//    }
//
//    @GetMapping("/anothor2")
//    public Results searchByA(String anothor, int page, int pageSize) {
//        Page<Article> articlePage = articleService.searchByAnother2(anothor,page,pageSize);
//        return new Results(1,articlePage,"查询成功");
//    }
//
//    @GetMapping("/summary2")
//    public Results searchBySummary2(String summary, int page, int pageSize) {
//        Page<Article> articlePage = articleService.searchBysummary2(summary, page, pageSize);
//        return new Results(1,articlePage,"查询成功");
//    }
//
//    @GetMapping("/periodical2")
//    public Results searchByPeriodical2(String periodical, int page, int pageSize) {
//        Page<Article> articlePage = articleService.searchByPeriodical2(periodical, page, pageSize);
//        return new Results(1,articlePage,"查询成功");
//    }
//
//    @GetMapping("/nativeKeyword2")
//    public Results searchByNativeKeyword2(String nativeKeyword, int page, int pageSize) {
//        Page<Article> articlePage = articleService.searchByNativeKeyword2(nativeKeyword, page, pageSize);
//        return new Results(1,articlePage,"查询成功");
//    }
//


    /**
     * 放置标题索引
     * @param requestBody：directory是UUID名称，titles是标题字符串数组，可以放多个文档
     * @return 1成功0失败
     */
    @PostMapping("/indexTitles")
    public ResponseEntity<String> putTitles(@RequestBody Map<String, Object> requestBody) {
        String directory = (String) requestBody.get("directory");
        List<String> titles = (List<String>) requestBody.get("titles");
        try {
            BulkRequest bulkRequest = new BulkRequest();
            for (String title : titles) {
                Map<String, Object> dataMap = new HashMap<>();
                dataMap.put("title", title);
                IndexRequest indexRequest = new IndexRequest(directory).id(UUID.randomUUID().toString()).source(dataMap);
                bulkRequest.add(indexRequest);
            }
            client.bulk(bulkRequest, RequestOptions.DEFAULT);
            return ResponseEntity.ok().body("Titles indexed successfully");
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * 放置作者索引
     * @param requestBody：directory是UUID名称，authors是作者字符串数组，可以放多个文档
     * @return 1成功0失败
     */
    @PostMapping("/indexAuthors")
    public ResponseEntity<String> putAuthors(@RequestBody Map<String, Object> requestBody) {
        String directory = (String) requestBody.get("directory");
        List<String> authors = (List<String>) requestBody.get("authors");
        try {
            BulkRequest bulkRequest = new BulkRequest();
            for (String author : authors) {
                IndexRequest indexRequest = new IndexRequest(directory);
                indexRequest.id(UUID.randomUUID().toString());
                Map<String, Object> dataMap = new HashMap<>();
                dataMap.put("author", author);
                indexRequest.source(dataMap);
                bulkRequest.add(indexRequest);
            }
            client.bulk(bulkRequest, RequestOptions.DEFAULT);
            return ResponseEntity.ok().body("Authors indexed successfully");
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * 放置关键词索引
     * @param requestBody：directory是UUID名称，keywords是关键词字符串数组，可以放多个文档
     * @return 1成功0失败
     */
    @PostMapping("/indexKeywords")
    public ResponseEntity<String> putKeywords(@RequestBody Map<String, Object> requestBody) {
        String directory = (String) requestBody.get("directory");
        List<String> keywords = (List<String>) requestBody.get("keywords");
        try {
            BulkRequest bulkRequest = new BulkRequest();
            for (String keyword : keywords) {
                IndexRequest indexRequest = new IndexRequest(directory);
                indexRequest.id(UUID.randomUUID().toString());
                Map<String, Object> dataMap = new HashMap<>();
                dataMap.put("keyword", keyword);
                indexRequest.source(dataMap);
                bulkRequest.add(indexRequest);
            }
            client.bulk(bulkRequest, RequestOptions.DEFAULT);
            return ResponseEntity.ok().body("Keywords indexed successfully");
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * 放置摘要索引
     * @param requestBody：directory是UUID名称，abstracts是摘要字符串数组，可以放多个文档
     * @return 1成功0失败
     */
    @PostMapping("/indexAbstracts")
    public ResponseEntity<String> putAbstracts(@RequestBody Map<String, Object> requestBody) {
        String directory = (String) requestBody.get("directory");
        List<String> abstracts = (List<String>) requestBody.get("abstracts");
        try {
            BulkRequest bulkRequest = new BulkRequest();
            for (String abst : abstracts) {
                IndexRequest indexRequest = new IndexRequest(directory);
                indexRequest.id(UUID.randomUUID().toString());
                Map<String, Object> dataMap = new HashMap<>();
                dataMap.put("abstract", abst);
                indexRequest.source(dataMap);
                bulkRequest.add(indexRequest);
            }
            client.bulk(bulkRequest, RequestOptions.DEFAULT);
            return ResponseEntity.ok().body("Abstracts indexed successfully");
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * 查找标题
     * @param //requestBody：query是查找的字符串
     * @return 返回json格式
     */
    @GetMapping("/searchTitle")
    public ResponseEntity<Map<String, Object>> searchArticlesByTitle(@RequestParam String query) {
        try {
            SearchRequest searchRequest = new SearchRequest("articles");
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            searchSourceBuilder.query(QueryBuilders.matchQuery("title", query));
            searchSourceBuilder.highlighter(new HighlightBuilder().field("title"));
            searchRequest.source(searchSourceBuilder);
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

            SearchHits searchHits = searchResponse.getHits();
            Map<String, Object> response = new HashMap<>();
            response.put("totalHits", searchHits.getTotalHits());

            List<Map<String, Object>> hits = new ArrayList<>();
            for (SearchHit hit : searchHits) {
                Map<String, Object> hitData = new HashMap<>();
                hitData.put("title", hit.getSourceAsMap().get("title"));
                hitData.put("score", hit.getScore());

                Text[] fragments = hit.getHighlightFields().get("title").fragments();
                List<String> contexts = new ArrayList<>();
                for (Text fragment : fragments) {
                    contexts.add(fragment.toString());
                }
                hitData.put("contexts", contexts);

                hits.add(hitData);
            }
            response.put("hits", hits);
            return ResponseEntity.ok().body(response);
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

}
